package base.thread_JUC2.chapter03.demo05;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;

public class FileSearch implements Runnable{
    // 查找的文件目录
    private String initPath;

    // 搜索的文件扩展名
    private String end;

    //存储找到的文件全路径名
    private List<String> results;

    private Phaser phaser;

    public FileSearch(String initPath, String end, Phaser phaser){
        this.initPath = initPath;
        this.end = end;
        this.phaser = phaser;
        results = new ArrayList<>();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" 我要开始等待了...");
        // 等待所有 FileSearch对象的创建
        int i = phaser.arriveAndAwaitAdvance();
        System.out.printf("%s: Starting \n", Thread.currentThread().getName());

        // 1、第一阶段
        File file = new File(initPath);
        if (file.isDirectory()) {
            directoryProcess(file);
        }
        // 没有结果就从phaser注销，并结束任务，否则当前线程就挂起等待phaser上其余线程任务
        if(!checkResults()){
            return ;//任务结束
        }

        // 2、第二阶段
        filterResults();

        // 再次检查结果
        if (!checkResults()) {
            return;
        }

        // 3、第三阶段
        showInfo();

        //结束phaser中的注册的所有线程
        phaser.arriveAndDeregister();
        System.out.printf("%s: Work completed.\n",Thread.currentThread().getName());
    }

    private void showInfo() {
        for (String result : results) {
            System.out.printf("%s: %s \n",Thread.currentThread().getName(), result);
        }
        //等待在phaser中注册的所有FileSearch线程的结束
        phaser.arriveAndAwaitAdvance();
    }

    // 删除一天以前修改过的文件
    private void filterResults() {
        ArrayList<String> newResults = new ArrayList<>();
        long milli = new Date().getTime();
        for (String result : results) {
            File file = new File(result);
            long fileMilli = file.lastModified();
            // 修改时间是否小于1天，小于就保留
            if (milli - fileMilli < TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)) {
                newResults.add(result);
            }
        }
        results = newResults;
    }

    private boolean checkResults() {
        if (results.isEmpty()) {
            System.out.printf("%s: Phase %d: 文件数是0.\n",Thread.currentThread().getName(),phaser.getPhase());
            System.out.printf("%s: Phase %d: End.\n",Thread.currentThread().getName(),phaser.getPhase());
            //没有结果。阶段已经完成，但没有更多的工作要做。取消注册的phaser
            phaser.arriveAndDeregister();
            return false;
        }else{
            //搜索到有结果。阶段完成。等待下一阶段的继续
            System.out.printf("%s: Phase %d: %d results.\n",Thread.currentThread().getName(), phaser.getPhase(), results.size());
            phaser.arriveAndAwaitAdvance();
            return true;
        }
    }

    // 处理目录
    private void directoryProcess(File file) {
        File[] files = file.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) {
                    directoryProcess(f);
                }else{
                    fileProcess(f);
                }
            }
        }
    }

    // 处理文件:将文件绝对路径添加到 List 集合中
    private void fileProcess(File f) {
        if (f.getName().endsWith(end)) {
            results.add(f.getAbsolutePath());
        }
    }
}
